package com.ctsi.security.service;

import com.ctsi.commons.event.BaseEvent;
import com.ctsi.commons.event.EventPublisherMan;
import com.ctsi.commons.util.UtilValidate;
import com.ctsi.commons.util.response.Page;
import com.ctsi.framework.mybatis.support.MybatisGenericDao;
import com.ctsi.security.ISecurity;
import com.ctsi.security.PermissionSer;
import com.ctsi.security.domain.Permission;
import com.ctsi.security.domain.RolePermission;
import com.ctsi.security.domain.SRole;
import com.ctsi.security.manager.impl.SecurityImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;

import java.util.*;


/**
 * 实现对系统功能的CRUD
 *
 * @author zhangjw
 *
 */
@Repository
public class PermissionService implements PermissionSer {
	private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(PermissionService.class);
	@Autowired
	private RoleSecurityService roleSecurityService;
    @Autowired
	private ISecurity security ;
    @Autowired
	private MybatisGenericDao dao;

	/**
	 * 发布事件
	 */
	@Autowired
	private EventPublisherMan publisherMan;


	@Override
	public void savePermission(Permission permission) {
		Assert.notNull(permission);
		String id=permission.getId();
		if(UtilValidate.isEmpty(id)) {
			permission.setId(UUID.randomUUID().toString());
		}
		dao.insert(permission);
		SecurityImpl.clearPermisiontypecache(permission.getPermissionId());
//		dao.saveObject(permission);
	}

	@Override
	public void updatePermission(Permission permission) {
//		dao.updateObject(permission);
		dao.update(permission);
		SecurityImpl.clearPermisiontypecache(permission.getPermissionId());
	}

	@Override
	public void removePermission(Permission permission) {
		dao.remove(permission);
		SecurityImpl.clearPermisiontypecache(permission.getPermissionId());
//		dao.removeObject(permission);
	}

	@Override
	public void removePermission(String id, String permissionId) {
//		dao.removeObject(com.gentlesoft.security.domain.Permission.class, id);
		Permission permission=new Permission();
		permission.setId(id);
		dao.remove(permission);
		// 删除rolePermission表中的数据,
		List<RolePermission> listRolePermission = roleSecurityService
				.findRolePermission(new String[] { "permissionId" },
						new Object[] { permissionId });
		for (RolePermission rolePermission : listRolePermission) {
			roleSecurityService.removeRolePermission(rolePermission.getId(),
					permissionId);
		}
		// 发布事件
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("type", "permissionId");
		List<String> list = new ArrayList<String>();
		list.add(permissionId);
		map.put("permissionId", list);
		BaseEvent be = new BaseEvent(this, "securityPermissionDo", map);
		this.publishEvent(be, null);
		SecurityImpl.clearPermisiontypecache(permissionId);
	}

	@Override
	public List<Permission> findPermissionAll() {
//		String hql = "from com.gentlesoft.security.domain.Permission";
//		List<Permission> list = dao.findAll(hql);
//		return list;
		return dao.find(Permission.class,(Map<String,Object>)null);
	}

	/* (non-Javadoc)
	 * @see com.gentlesoft.security.service.permissionSer#findPermission(java.lang.String[], java.lang.Object[])
	 */
	@Override
	public List<Permission> findPermission(String[] field, Object[] args) {
//		StringBuffer sbhql = new StringBuffer();
//		sbhql.append("from com.gentlesoft.security.domain.Permission");
//		for (int i = 0; i < field.length; i++) {
//			if (i == 0) {
//				sbhql.append(" where " + field[i] + "=?");
//			} else {
//				sbhql.append(" and " + field[i] + "=?");
//			}
//		}
//		List<Permission> list = dao.findAll(sbhql.toString(), args);
//		return list;
		if(field==null||args==null) {
			return new ArrayList<Permission>(0);
		}
		Assert.isTrue(field.length==args.length,"fields's length is not equal args's length");
		Map<String,Object> params=new HashMap<String, Object>();
		for(int i=0;i<field.length;i++) {
			params.put(field[i].toLowerCase(), args[i]);
		}
		return dao.find(Permission.class, params);
	}

	@Override
	public List<Permission> findPermission(String userLogin,String dataObjectType,String action,Map<String,? extends Object> params){
		Map<String,Object> args=new HashMap<String, Object>();
		if(params!=null) {
		   for(String item : params.keySet()) {
			   args.put(item.toLowerCase(), params.get(item));
		   }
		}
		if(UtilValidate.isEmpty(userLogin)||UtilValidate.isEmpty(dataObjectType)||UtilValidate.isEmpty(action)) {
			logger.warn("There are arguments is Empty!");
		}else {
			if(security.isControl(userLogin, dataObjectType, action)) {
				List<String> dataObjectIds=security.getDataObjectIds(userLogin, dataObjectType, action);
				if(UtilValidate.isNotEmpty(dataObjectIds)) {
					if(dataObjectIds.size()==1) {
						args.put("dataObjectsId", dataObjectIds.get(0));
					}else {//>1
						args.put("dataObjectsIds", dataObjectIds);
					}
				}else {
					return new ArrayList<Permission>(0);
				}
			}
		}
		return dao.find(Permission.class, args);
		
//		StringBuilder hsql=new StringBuilder();//hsql Builder
//		//返回结果
//		List<Permission> result=new LinkedList<Permission>();
//		hsql=hsql.append("from com.gentlesoft.security.domain.Permission");
//		List<Object> args=new LinkedList<Object>();
//		//判断传递过来的参数是否为null
//		if(params==null){
//			logger.debug("根据数据权限查询所有的功能ID，对应的数据对象类型为{}",dataObjectType);
//		}else{
//			//不为null
//			hsql.append(" where ");
//			for(String key:params.keySet()){
//			  hsql.append(key).append("=").append("?");
//			  hsql.append(" and");
//			  args.add(params.get(key));
//			}
//		   //去掉最后一个and
//			if(hsql.toString().endsWith("and")){
//				hsql.delete(hsql.lastIndexOf("and"),hsql.lastIndexOf("and")+3);
//			}
//		}
//		logger.debug("The HSQL is {}",hsql);
//		logger.debug("The HSQL's params is {}",args);
//		//加入数据权限
//		//是否控制数据权限
//		if(!security.isControl(userLogin, dataObjectType,action)){//不控制数据权限
//			logger.debug("{}对于{}不控制数据权限",userLogin,dataObjectType);
//		}else{//控制数据权限
//			List<String> dataObjectIds=security.getDataObjectIds(userLogin, dataObjectType,action);
//			//判断是否为空
//			if(UtilValidate.isEmpty(dataObjectIds)){
//				logger.debug("{}对于{}控制数据权限,dataObjects is NULL",userLogin,dataObjectType);
//			}else{//不为空
//				if(params==null){//传递参数为空时
//					hsql.append(" where ");
//				}else{//传递参数非空
//					hsql.append(" and ");
//				}
//				//判断长度是否为1
//				if(dataObjectIds.size()==1){
//					hsql.append(" dataObject=?");
//					args.add(dataObjectIds.get(0));
//				}else{//Length>1
//					hsql.append(" dataObject in (?");
//					for(int i=0;i<dataObjectIds.size()-1;i++){
//						hsql.append(",?");
//					}
//					hsql.append(")");
//					args.addAll(dataObjectIds);
//				}
//			}
//
//		}
//		if(logger.isDebugEnabled()) {
//			logger.debug("The Last hsql is {}",hsql);
//			logger.debug("The last hsql's params is {}",args);
//		}
//		result=dao.findAll(hsql.toString(),args.toArray());
//		return result;
	}

	@Override
	public List<String> findPermissionIdByPermType(String permissionTypeId) {
		Map<String,Object> params=new HashMap<String, Object>(1);
		params.put("permissiontypeid", permissionTypeId);
		List<Permission> resultTemp=dao.find(Permission.class, params);
		if(UtilValidate.isEmpty(resultTemp)) {
			return new ArrayList<String>(0);
		}else {
			List<String>result=new ArrayList<String>(resultTemp.size());
			for (Permission permItem: resultTemp) {
				result.add(permItem.getPermissionId());
			}
			return result;
		}
//		StringBuffer sbhql = new StringBuffer();
//		sbhql
//				.append("select perm.permissionId from com.gentlesoft.security.domain.Permission as perm where perm.permissionTypeId=?");
//		return dao.findAll(sbhql.toString(), new Object[] { permissionTypeId });
	}

	
	@Override
	public List<Permission> findPermissionByPermType(String permissionTypeId) {
		Map<String,Object> params=new HashMap<String, Object>(1);
		params.put("permissiontypeid", permissionTypeId);
		return dao.find(Permission.class, params);

	}
	


//	/**
//	 * 通过hsql分页查找po数据 firstnode表示记录的起始点，从0开始 noderange表示需返回的总数，如果firstnode +
//	 * noderange>纪录总数，则返回空的list
//	 *
//	 * @param hsql
//	 * @param args
//	 * @param firstnode
//	 * @param noderange
//	 * @return
//	 */
//	public List<Permission> findPermission(String[] field, Object[] args,
//			final int firstnode, final int noderange) {
//		StringBuffer sbhql = new StringBuffer();
//		sbhql.append("from com.gentlesoft.security.domain.Permission");
//		for (int i = 0; i < field.length; i++) {
//			if (i == 0) {
//				sbhql.append(" where " + field[i] + "=?");
//			} else {
//				sbhql.append(" and " + field[i] + "=?");
//			}
//		}
//		List<Permission> list = dao.findAll(sbhql.toString(), args, firstnode,
//				noderange);
//		return list;
//	}

//	/**
//	 * 查询数据
//	 *
//	 * @param firstnode
//	 * @param noderange
//	 * @return
//	 */
//	public List<Permission> findPermission(int firstnode, int noderange) {
//		String hql = "from com.gentlesoft.security.domain.Permission";
//		List<Permission> list = dao.findAll(hql, firstnode, noderange);
//		return list;
//	}

	@Override
	public Page<Permission> queryPermission(int pageSize, int startIndex) {
		Page<Permission> resultTemp=dao.queryPage(Permission.class.getName()+".selectByMap", Collections.EMPTY_MAP, startIndex, pageSize);
		return resultTemp;
//		String hql = "select per.id,per.permissionId,per.permissionName,per.description,per.dataObject,per.permissionTypeId,pertype.permissionTypeName from com.gentlesoft.security.domain.Permission as per,com.gentlesoft.security.domain.PermissionType as pertype where per.permissionTypeId=pertype.permissionTypeId";
//		Page<Object[]> listPermission = dao.findPageByQuery(hql, pageSize,
//				startIndex, new Object[] {});
//		List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
//		List<Object[]> list = listPermission.getResult();
//		for (int i = 0; i < list.size(); i++) {
//			Object[] temp = list.get(i);
//			Map<String, Object> map = new HashMap<String, Object>();
//			for (int j = 0; j < temp.length; j++) {
//				temp[j] = temp[j] == null ? "" : temp[j];
//				if (j == 0)
//					map.put("id", temp[j]);
//				if (j == 1)
//					map.put("permissionId", temp[j]);
//				if (j == 2)
//					map.put("permissionName", temp[j]);
//				if (j == 3)
//					map.put("description", temp[j]);
//				if (j == 4)
//					map.put("dataObject", temp[j]);
//				if (j == 5)
//					map.put("permissionTypeId", temp[j]);
//				if (j == 6)
//					map.put("permissionTypeName", temp[j]);
//			}
//			listMap.add(map);
//		}
//		Page page = new Page(startIndex, listPermission.getTotalCount(),
//				pageSize, listMap);
//		return page;
	}

	@Override
	public Page queryPermission(int pageSize, int startIndex,
			String permissionTypeId) {
//		String hql = "from com.gentlesoft.security.domain.Permission as per where per.permissionTypeId=?";
//		return dao.findPageByQuery(hql, pageSize, startIndex,
//				new Object[] { permissionTypeId });
		Map<String,Object> params=new HashMap<String, Object>(1);
		params.put("permissionTypeId", permissionTypeId);
		return dao.queryPage(Permission.class.getName()+".selectByMap", params, startIndex, pageSize);
	}

	
	@Override
	public Page<Permission>  queryPermission(String userLoginId, String dataObjectType,String action,String searchPermId,
			String permissionName, int pageSize, int startIndex,
			String permissionTypeId) {
		Page<Permission> result=new Page<Permission>();//返回结果
		//构建Sql参数
		Map<String,Object> params=new HashMap<String, Object>();
		//加入查询参数
		if(UtilValidate.isNotEmpty(searchPermId)){
			params.put("permissionId", searchPermId);
		}
		if(UtilValidate.isNotEmpty(permissionName)){
			params.put("permissionName", permissionName);
		}
		if(UtilValidate.isNotEmpty(permissionTypeId)){
			params.put("permissionTypeId", permissionTypeId);
		}
		//判断是否控制数据权限
		if(!security.isControl(userLoginId, dataObjectType,action)){//不控制数据权限
			logger.info("{}查询功能不控制数据权限",userLoginId);
		}else{//控制数据权限
			List<String> dataObjectIds=security.getDataObjectIds(userLoginId, dataObjectType,action);
			//判断是否为空
			if(UtilValidate.isEmpty(dataObjectIds)){
				//为空
				logger.info("{}查询功能，数据对象集为空",userLoginId);
				return result;
			}
			//列表长度大于等于1
			logger.info("{}查询功能，数据对象集为{}",userLoginId,dataObjectIds);
			params.put("dataObjectIds", dataObjectIds);
		}
        //输出查询结果
		result=dao.queryPage(Permission.class.getName().concat(".selectMulti"), params, startIndex, pageSize);
		return result;
		}

	@Override
	public Page<Permission> queryPermission(String userLoginId,String dataObjectType, String action, String searchPermId,
			String permissionName, String pType, int pageSize, int startIndex,String permissionTypeId) {
		Page<Permission> result=new Page<Permission>();//返回结果
		//构建Sql参数
		Map<String,Object> params=new HashMap<String, Object>();
		//加入查询参数
		if(UtilValidate.isNotEmpty(searchPermId)){
			params.put("permissionId", searchPermId);
		}
		if(UtilValidate.isNotEmpty(permissionName)){
			params.put("permissionName", permissionName);
		}
		if(UtilValidate.isNotEmpty(permissionTypeId)){
			params.put("permissionTypeId", permissionTypeId);
		}
		if(UtilValidate.isNotEmpty(pType)){
			params.put("pType", pType);
		}
		//判断是否控制数据权限
		if(!security.isControl(userLoginId, dataObjectType,action)){//不控制数据权限
			logger.info("{}查询功能不控制数据权限",userLoginId);
		}else{//控制数据权限
			List<String> dataObjectIds=security.getDataObjectIds(userLoginId, dataObjectType,action);
			//判断是否为空
			if(UtilValidate.isEmpty(dataObjectIds)){
				//为空
				logger.info("{}查询功能，数据对象集为空",userLoginId);
				return result;
			}
			//列表长度大于等于1
			logger.info("{}查询功能，数据对象集为{}",userLoginId,dataObjectIds);
			params.put("dataObjectIds", dataObjectIds);
		}
        //输出查询结果
		result=dao.queryPage(Permission.class.getName().concat(".selectMulti"), params, startIndex, pageSize);
		return result;
	}
	@Override
	public boolean valPermissionId(String permissionId) {
//		String hql = "from com.gentlesoft.security.domain.Permission where permissionId=?";
//		List<Permission> list = dao.findAll(hql, new Object[] { permissionId });
		Map<String,Object> params=new HashMap<String, Object>(1);
		params.put("permissionid", permissionId);
		List<Permission> list=dao.find(Permission.class, params);
		if (list.size() > 0) {
			return true;
		} else {
			return false;
		}
	}
	
	@Override
	public Permission findByPermission(String permissionId){
		String [] field = new String[]{"PERMISSIONID"};
		Object[] args = new Object[]{permissionId};
		List<Permission> list =  findPermission(field,  args) ;
		if(list == null || list.size() !=1){
			return null;
		}else{
			return list.get(0);
		}		  
	}

	
	@Override
	public Page<Permission> queryPermByLoginId(String userLoginId,String dataObjectType,String action,String loginId,Map<String,Object> conds,int start){
		Page<Permission> result=new Page<Permission>();//返回结果
		//构建Sql参数
		Map<String,Object> params=new HashMap<String, Object>();
		//加入查询参数
		if(UtilValidate.isNotEmpty(loginId)){
			params.put("loginId", loginId);
		}
		if(UtilValidate.isNotEmpty(conds)){
			params.putAll(conds);
		}
		if(UtilValidate.isNotEmpty(userLoginId)&&UtilValidate.isNotEmpty(dataObjectType)){
			//判断是否控制数据权限
			if(!security.isControl(userLoginId, dataObjectType,action)){//不控制数据权限
				logger.info("{}查询功能不控制数据权限",userLoginId);
			}else{//控制数据权限
				List<String> dataObjectIds=security.getDataObjectIds(userLoginId, dataObjectType,action);
				//判断是否为空
				if(UtilValidate.isEmpty(dataObjectIds)){
					//为空
					logger.info("{}查询功能，数据对象集为空",userLoginId);
					return result;
				}
				//列表长度大于等于1
				logger.info("{}查询功能，数据对象集为{}",userLoginId,dataObjectIds);
				params.put("dataObjectIds", dataObjectIds);
			}
		}
		//输出查询结果
		result=dao.queryPage(Permission.class.getName().concat(".selectPerm"), params, start, Page.DEFAULT_PAGE_SIZE);
		return result;

	}
	

	@Override
	@SuppressWarnings("unchecked")
	public List<Permission> queryAllPermByUserId(String userLoginId){
		Map<String,Object> params=new HashMap<String, Object>(1);
		params.put("loginId", userLoginId);
		return (List<Permission>)dao.queryForList(Permission.class.getName().concat(".selectPerm"),params);
	}

	@Override
	public Page<Permission> queryPermByLoginId(String loginId,Map<String,Object> conds,int start){
		return queryPermByLoginId(null,null,"all",loginId,conds,start);
	}

	/**
	 * 发布事件
	 *
	 * @param baseEvent
	 * @param args
	 */
	private void publishEvent(BaseEvent baseEvent, Object args) {
		publisherMan.getEventPublisher().publishEvent(baseEvent, args);
	}

	public EventPublisherMan getPublisherMan() {
		return publisherMan;
	}

	public void setPublisherMan(EventPublisherMan publisherMan) {
		this.publisherMan = publisherMan;
	}

	

	@Override
	public List<SRole> getSRoleByPartyId(String userLoginId, String dataObjectType, String action, String permission){
		List<SRole> result=new ArrayList<SRole>();//返回结果
		Map<String,Object> params=new HashMap<String, Object>();//查询参数
		params.put("permissionId", permission);
		//判断是否控制数据权限
		if(!security.isControl(userLoginId, dataObjectType,action)){//不控制数据权限
			logger.debug("{} is not controlled for {}",userLoginId,dataObjectType);
		}else{//控制数据权限
			List<String> dataObjectIds=security.getDataObjectIds(userLoginId, dataObjectType,action);//数据对象集
			//判断是否为空
			if(UtilValidate.isNotEmpty(dataObjectIds)){//不为空
				logger.debug("{} is controlled for {},the dataObjectIds are {}",new Object[]{userLoginId,dataObjectType,dataObjectIds});
				//判断长度是否为１
				if(dataObjectIds.size()==1){//等于１
					params.put("dataObjectId",dataObjectIds.get(0));
				}else{//大于１
					params.put("dataObjectIds", dataObjectIds);
				}
			}else{//为空
			   logger.debug("{} is controlled for {},but the dataObjectIds is null");
				return result;
			}
		}
		result=(List<SRole>)dao.queryForList(SRole.class.getName().concat(".querySRoleByPerId"),params);
		return result;
	}

	
}
